package com.example.waitdemo.config;

import com.example.waitdemo.utils.HttpResult;
import com.example.waitdemo.utils.StringNullUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

/**
 * @Description
 * @ClassName ClassNotNullAspect
 * @Author jiang_11445266119198
 * @Date 2022/7/13 12:27
 */
@Aspect     // 切面
@Component  // 表示这是一个bean,由Spring进行管理 或者说输入spring
public class ClassNotNullAspect {

    // 配置织入点
    @Pointcut("@annotation(com.example.waitdemo.config.ClassNotNull)")
    public void ClassNotNullPointcut() {
    }

    @Around("ClassNotNullPointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        //System.out.println("---------");
        Object arg = joinPoint.getArgs()[0];
        Parameter[] parameters = method.getParameters();
        //获取class对象
        Class<?> aClass = parameters[0].getType();

        //获取当前对象所有属性  使用带Declared的方法可访问private属性
        Field[] declaredFields = aClass.getDeclaredFields();
        System.out.println("declaredFields = " + declaredFields.toString());
        for(Field field:declaredFields){
            //开启访问权限
            field.setAccessible(true);
            //使用此方法 field.get(Object obj) 可以获取  当前对象这个列的值
            Object o = field.get(arg);
            //System.out.println("o = " + o);
            Annotation annotation = field.getDeclaredAnnotation(NotNotNull.class);
            //如果没有设置当前注解 不用校验
            if(annotation == null){
                continue;
            }
            //如果设置了当前注解，但是没有值，抛出异常
            if(StringNullUtil.isEmpty(String.valueOf(o))){
                //获取注解接口对象
                NotNotNull notNull = (NotNotNull)annotation;
                if(StringNullUtil.isNotEmpty(notNull.message())){
                    System.out.println("notNull.message() = " + notNull.message());
                    //设置了注解message值 直接返回
                    //throw new RuntimeException(notNull.message());
                    return HttpResult.newError(notNull.message());
                }else{
                    System.out.println("field.getName() = " + field.getName()+" is null");
                    //没有设置可以拼接
                    //throw new RuntimeException(field.getName()+" is null");
                    return HttpResult.newError(field.getName()+" is null");
                }
            }
        }
        return joinPoint.proceed();
    }
}
